package heartbeat;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Executor;

import org.json.JSONException;


public class Main 
{
	protected static List<String> mChannelNames;
	
	public static void main(String[] args) throws JSONException, IOException
	{
		final PmHeartbeat hb = new PmHeartbeat();
		PmTcpClient pClient1 = (PmTcpClient)(hb.addClient("sdm07.wv.mentorg.com", 9004));
		//TcpClient pClient2 = hb.addClient("sdm07.wv.mentorg.com", 9011);
		PCallback<MessageCBType> simpleEchoCallback = new PCallback<MessageCBType>()
		{
			@Override
			public void invoke(MessageCBType result) 
			{
				TcpClient pReceiver = result.client();
				System.out.println(pReceiver);
				Packet pPacket = result.packet();
				System.out.println(pPacket.channel());
				System.out.println(pPacket.message());
				
				//Get the channel name from the packet.
				//String cName = hb.channelName(pReceiver, pPacket.channel());
				
				//Get the channel number from the packet.
				//Integer cNum = hb.channelNumber(pReceiver, cName);
				
				//Check for null on the channel number.
				//if(cNum == null) {}
				
				//Write the message back to the server using the channel name.
				//The channelName function returns null if the channel number passed in does not map to anything
				//if(cName == null)
				//	return;
				
				//hb.write(pReceiver, cName, pPacket.message());
				
			}
		};
		
		PCallback<ChannelsCBType> channelsReceivedCallback = new PCallback<ChannelsCBType>()
		{
			@Override
			protected void invoke(ChannelsCBType result)
			{
				TcpClient pReceiver = result.client();
				mChannelNames = result.channels();
				
				//Send authentication to the PM heartbeat server.
				try 
				{
					((PmTcpClient)pReceiver).sendEncodedConnectionIdAuthentication("px2TxFlxS3ibHMR%2BW1uog%2FkB%2BDiMVsUZ7EGiUx0Pjopn833ECiDvJM56G%2Fe3mJ8SV3qh1B5zFPTRh6jmPHOu7g%3D%3D");
				}
				catch(Exception e) {}
			}
			
		};
		
		PCallback<MessageCBType> authenticatedCallback = new PCallback<MessageCBType>()
		{
			@Override
			protected void invoke(MessageCBType result) 
			{
				TcpClient pReceiver = result.client();
				
				//Subscribe to each channel.
				pReceiver.subscribeTo(mChannelNames);
			}
					
		};
		
		PCallback<MessageCBType> batchJobCompletedCallback = new PCallback<MessageCBType>()
		{
			@Override
			protected void invoke(MessageCBType result) 
			{
				@SuppressWarnings("unused")
				TcpClient pReceiver = result.client();
				@SuppressWarnings("unused")
				Packet batchJobResults = result.packet();
			}
							
		};
		
		PCallback<MessageCBType> batchJobUpdateCallback = new PCallback<MessageCBType>()
		{
			@Override
			protected void invoke(MessageCBType result) 
			{
				@SuppressWarnings("unused")
				TcpClient pReceiver = result.client();
				@SuppressWarnings("unused")
				Packet batchJobUpdate = result.packet();
			}
									
		};
		
		hb.setOnMessageCallback(pClient1, simpleEchoCallback);
		hb.setOnChannelsReceivedCallback(pClient1, channelsReceivedCallback);
		hb.setOnAuthenticationCallback(pClient1, authenticatedCallback);
		hb.setOnBatchJobCompletedCallback(pClient1, batchJobCompletedCallback, "14");
		hb.setOnBatchJobUpdateCallback(pClient1, batchJobUpdateCallback, "14");
		//hb.setOnMessageCallback(pClient2, simpleEchoCallback);
		//hb.setOnChannelsReceivedCallback(pClient2, channelsReceivedCallback);
		
		//Write can be called before or after starting the heartbeat executor. Messages written before are added to a queue that gets emptied once the executor starts.
		//JSONObject msg = new JSONObject().put("channelNumber", "test");
		//hb.write(pClient1, new Packet(6, msg));
		
		//Channel names/JSONObjects can be used when writing, but will not be sent until the channel list has been received and the channel name is valid.
		//JSONObject msg2 = new JSONObject().put("channelName", "test");
		//hb.write(pClient2, "WORKFLOW_HEARTBEAT_CLIENT_REQUEST", msg2);
		
		
		//The executor runs in a separate thread. Messages can still be written after calling execute.
		Executor ex = new ThreadPerTaskExecutor();
		ex.execute(hb);
		
		//JSONObject msg3 = new JSONObject().put("afterExecute", "test");
		//hb.write(pClient1, "Jeff's Channel", msg3);
		
		//Test a long message.
		//String lMsg = "";
		//for(int i = 0; i < 10000; ++i)
		//	lMsg += "a";
		//lMsg += 'b';
		//JSONObject msg4 = new JSONObject().put("longMessage", lMsg);
		//hb.write(pClient2, "WORKFLOW_HEARTBEAT_CLIENT_REQUEST", msg4);
		
	}
}
